package es.upm.gib.mappingAPI2;

import java.io.Serializable;
import java.util.*;

/**
 * This class is represented by some metadata:
 * - Format version of the mapping
 * - Name of the mapping
 * - description of the mapping
 * - databaseinfo of the mapping
 * - List of authors of the mapping
 * - Date of creation of the mapping
 * - Last author who modifies the mapping
 * - Date of last modification of the mapping
 * - List of abbreviations
 * - CustomData
 *
 */
public class MappingMetadata implements Serializable{

    //=======================================================================
    //ATTRIBUTES
    //=======================================================================

    /**
     * the version of the mapping format described in the file. This value should be fixed for all the project, unless some format changes are required
     */
    private String mappingFormatVersion;

    /**
     * the name that unequivocally identifies this mapping
     */
    private String mappingName;

    /**
     * a free text description of this mapping
     */
    private String description;

    /**
     * several data can be stored about the physical database being mapped
     */
    private DatabaseInfo databaseInfo;

    /**
     * list of people involved in developing this mapping
     */
    private Set<String> authors;

    /**
     * date in which this mapping was first created
     */
    private Date creationDate;

    /**
     * the person who last modified this mapping
     */
    private String lastModifiedBy;

    /**
     * when this mapping was modified for the last time.
     */
    private Date lastModificationDate;

    /**
     * list of namespaces used for storing the mapping
     */
    private Map<String, String> abbreviationList;

    /**
     * custom data of the mapping
     */
    private CustomData customData;

    //=======================================================================
    //CONSTRUCTORS
    //=======================================================================

    /**
     * Constructor
     * @param mappingFormatVersion version of mapping
     */
    public MappingMetadata(String mappingFormatVersion) {
        this.mappingFormatVersion = mappingFormatVersion;
        this.databaseInfo = new DatabaseInfo();
        this.authors = new HashSet<String>();
        this.creationDate = new Date();
        this.lastModificationDate = new Date();
        this.abbreviationList = new HashMap<String, String>();
        this.customData = new CustomData();
    }


    /**
     * Constructor
     */
    public MappingMetadata() {
        this.databaseInfo = new DatabaseInfo();
        this.authors = new HashSet<String>();
        this.creationDate = new Date();
        this.lastModificationDate = new Date();
        this.abbreviationList = new HashMap<String, String>();
        this.customData = new CustomData();

    }

    //=======================================================================
    //PUBLIC METHODS
    //=======================================================================

    /**
     * This method retrieves the version of the mapping
     *
     * @return the version of the mapping
     */
    public String getMappingFormatVersion() {
        return mappingFormatVersion;
    }

    /**
     * This method sets the version of the mapping
     *
     * @param mappingFormatVersion version of the mapping
     */
    public void setMappingFormatVersion(String mappingFormatVersion) {
        this.mappingFormatVersion = mappingFormatVersion;
    }

    /**
     * This method returns the name of the mapping
     *
     * @return name of the mapping
     */
    public String getMappingName() {
        return mappingName;
    }

    /**
     * This method sets the name of the mapping
     *
     * @param mappingName name of the mapping
     */
    public void setMappingName(String mappingName) {
        this.mappingName = mappingName;
    }

    /**
     * This method returns the description of the mapping
     *
     * @return description of the mapping
     */
    public String getDescription() {
        return description;
    }

    /**
     * This method sets the description of the mapping
     *
     * @param description description of the mapping
     */
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     * This method returns information of the database
     *
     * @return information of the database
     */
    public DatabaseInfo getDatabaseInfo() {
        return databaseInfo;
    }

    /**
     * This method sets information of the database
     *
     * @param databaseInfo information of the database
     */
    public void setDatabaseInfo(DatabaseInfo databaseInfo) {
        this.databaseInfo = databaseInfo;
    }

    /**
     * This method returns the list of authors of the mapping
     *
     * @return authors of the mapping
     */
    public Set<String> getAuthors() {
        return authors;
    }

    /**
     * This method sets the list of authors of the mapping
     *
     * @param authors list of authors
     */
    public void setAuthors(Set<String> authors) {
        this.authors = authors;
    }

    /**
     * This method returns the creation date of the mapping
     *
     * @return the creation date of the mapping
     */
    public Date getCreationDate() {
        return creationDate;
    }

    /**
     * This method sets the creation date of the mapping
     *
     * @param creationDate creation date of the mapping
     */
    public void setCreationDate(Date creationDate) {
        this.creationDate = creationDate;
    }

    /**
     * This method returns the last author who modifies the mapping
     *
     * @return last author who modifies the mapping
     */
    public String getLastModifiedBy() {
        return lastModifiedBy;
    }

    /**
     * This method sets the last author who modifies the mapping
     *
     * @param lastModifiedBy last author who modifies the mapping
     */
    public void setLastModifiedBy(String lastModifiedBy) {
        this.lastModifiedBy = lastModifiedBy;
    }

    /**
     * This method returns the last modification date of the mapping
     *
     * @return the last modification date of the mapping
     */
    public Date getLastModificationDate() {
        return lastModificationDate;
    }

    /**
     * This method sets the last modification date of the mapping
     *
     * @param lastModificationDate last modification date of the mapping
     */
    public void setLastModificationDate(Date lastModificationDate) {
        this.lastModificationDate = lastModificationDate;
    }

    /**
     * This method returns the list of abbreviations of the mapping
     *
     * @return abbreviation list of the mapping
     */
    public Map<String, String> getAbbreviationList() {
        return abbreviationList;
    }

    /**
     * This method sets the list of abbreviations of the mapping
     *
     * @param abbreviationList abbreviation list
     */
    public void setAbbreviationList(Map<String, String> abbreviationList) {
        this.abbreviationList = abbreviationList;
    }

    /**
     * This method adds a new value to the custom data of the mapping
     *
     * @param key key of the new value
     * @param value value to add
     */
    public void addValueToCustomData(String key, String value) {
        this.customData.addValue(key, value);
    }

    /**
     * This method sets the custom data of the mapping
     *
     * @param customData CustomData to add
     */
    void setCustomData(CustomData customData) {
        this.customData = customData;
    }

    /**
     * This method returns the custom data of the mapping
     *
     * @return custom data of the mapping
     */
    public CustomData getCustomData() {
        return customData;
    }

    /**
     * This method adds a new author to the list of authors of the mapping
     *
     * @param author name of author to add
     */
    public void addAuthor(String author) {
        if ((!authors.isEmpty()) && (!authors.contains(author))) {
            authors.add(author);
        } else if (authors.isEmpty()) {
            authors.add(author);
        }
    }


}
